package browserUI
{
	import dev.touchswipe.shared.touchLib.TouchManager;
	import dev.touchswipe.shared.touchLib.TouchPoint;
	
	import flash.display.BitmapData;
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.FocusEvent;
	import flash.events.ProgressEvent;
	import flash.events.TouchEvent;
	import flash.events.TransformGestureEvent;
	import flash.geom.Matrix;
	import flash.geom.PerspectiveProjection;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.html.HTMLHost;
	import flash.html.HTMLLoader;
	import flash.net.URLRequest;
	
	[Event(type="browserUI.JSEvent",name="inputFocus")]
	
	public class WebBrowser extends Sprite
	{
		public var html:HTMLLoader;
		private var htmlMask:Shape;
		
		public var hasFocus:Boolean;
		public var tabID:int;
		
		private var _width:int=100;
		private var _height:int=100;
		
		public function WebBrowser()
		{
			super();
			
			htmlMask=new Shape();
			addChild(htmlMask);
			
			html= new HTMLLoader();
			html.htmlHost=new HTMLHost();
			html.addEventListener(Event.COMPLETE,function(event:Event):void{
				var evt:BrowserEvent=new BrowserEvent(BrowserEvent.PAGE_LOADED);
				evt.url=html.location;
				dispatchEvent(evt);
			});
			html.addEventListener(Event.HTML_DOM_INITIALIZE,onDOMInit);
			html.addEventListener(FocusEvent.FOCUS_IN,onFocusIn);
			
			html.mask=htmlMask;
			addChild(html);
			
			_touchManager=new TouchManager();
						
			html.addEventListener(TouchEvent.TOUCH_BEGIN,onTouchBegin);
			addEventListener(TouchEvent.TOUCH_MOVE,onTouchMove);
			addEventListener(TouchEvent.TOUCH_END,onTouchEnd);
			addEventListener(Event.ENTER_FRAME,onEnterFrame);
			
			redraw();
		}
		
		private function insertText(text:String,object:Object):void{
			var start:int=object.selectionStart;
			object.value=object.value.substring(0,start)+text+object.value.substring(object.selectionEnd);
			object.setSelectionRange(start+1,start+1);
		}
		
		private function backSpace(object:Object):void{
			var start:int=object.selectionStart;
			if(object.selectionStart==object.selectionEnd){
				object.value=object.value.substring(0,start-1)+object.value.substring(start);
				object.setSelectionRange(start-1,start-1);
			}
			else{
				object.value=object.value.substring(0,start)+object.value.substring(object.selectionEnd);
				object.setSelectionRange(start,start);
			}
		}
		
		public function handleKeyPress(keyID:String):void{
			if(currentFocus){
				if(currentFocus["tagName"]=="INPUT"&&(currentFocus["type"]=="text"||currentFocus["type"]=="password")){
					switch(keyID.toUpperCase()){
						case Key.ENTER:
							currentFocus.form.submit();
							break;
						case Key.BACK:
							backSpace(currentFocus);
							break;
						default:
							insertText(keyID,currentFocus);
					}
				}
				if(currentFocus["tagName"]=="TEXTAREA"){
					switch(keyID.toUpperCase()){
						case Key.ENTER:
							currentFocus.value+=keyID;
							break;
						case Key.BACK:
							
							break;
						default:
							insertText(keyID,currentFocus);
					}
				}
			}
			
		}
		
		private function onDOMInit(event:Event):void{
			html.height=_height;
			html.width=_width;
			html.x=0;
			html.y=0;
			_scale=1;
			html.scaleX=1;
			html.scaleY=1;
			_scaleCenter=new Point(0,0);
			_transformPoint=new Point(0,0);
			dispatchEvent(new JSEvent(JSEvent.INPUT_BLUR,event.target));
			html.window.addEventListener( "focus",onJSFocus,true);
			html.window.addEventListener( "blur", onJSBlur, true );
			html.window.document.onselectstart=function():Boolean{return _selectEnabled;};
		}
		
		public function get currentFocus():Object{
			return html.window.document.activeElement;
		}
		
		private function onFocusIn(event:FocusEvent):void{
			if(currentFocus&&((currentFocus["tagName"]=="INPUT"&&(currentFocus["type"]=="text"||currentFocus["type"]=="password"))||currentFocus["tagName"]=="TEXTAREA"))
				dispatchEvent(new JSEvent(JSEvent.INPUT_FOCUS,currentFocus));
		}
		
		private function onJSFocus(event:Object):void{
			if((event.target["tagName"]=="INPUT"&&(event.target["type"]=="text"||event.target["type"]=="password"))||event.target["tagName"]=="TEXTAREA")
				dispatchEvent(new JSEvent(JSEvent.INPUT_FOCUS,event.target));
		}
		
		private function onJSBlur(event:Object):void{
			dispatchEvent(new JSEvent(JSEvent.INPUT_BLUR,event.target));
		}
		
		public function browseTo(url:String):void{
			html.load(new URLRequest(url));
		}
		
		public override function get width():Number{
			return _width;
		}
		public override function set width(value:Number):void{
			_width=value;
			redraw();
		}
		public override function get height():Number{
			return _height;
		}
		public override function set height(value:Number):void{
			_height=value;
			redraw();
		}
		
		private function redraw():void{
			htmlMask.graphics.clear();
			htmlMask.graphics.beginFill(0);
			htmlMask.graphics.drawRect(0,0,_width,_height);
			html.width=_width;
			html.height=Math.max(_height,html.contentHeight);
		}
		
		private var _touchManager:TouchManager;
		private var _selectEnabled:Boolean=true;
		private var _startZoom:Number;
		public function onTouchBegin(event:TouchEvent):void{
			_selectEnabled=false;
			_touchManager.updatePoint(event);
			redraw();
			_startZoom=_scale;
			if(_touchManager.activePoints==2){
				var points:Vector.<TouchPoint>=_touchManager.getCurrentPoints();
				_scaleCenter.x=(points[0].current.x+points[1].current.x)/2;
				_scaleCenter.y=(points[0].current.y+points[1].current.y)/2-y;
				_transformPoint.x=(_scaleCenter.x-html.x)/_scale;
				_transformPoint.y=(_scaleCenter.y-html.y)/_scale;
			}
			
		}
		
		public function onTouchMove(event:TouchEvent):void{
			if(_touchManager.activePoints==1){
				var t:TouchPoint=_touchManager.getUpdatedPoint(event);
				_scaleCenter.x+=t.currentDelta.x;
				_scaleCenter.y+=t.currentDelta.y;
			}
			else{
				_touchManager.updatePoint(event);
				var points:Vector.<TouchPoint>=_touchManager.getCurrentPoints();
				var l:Number=points[0].current.subtract(points[1].current).length;
				var l2:Number=points[0].start.subtract(points[1].start).length;
				_scale=_startZoom*l/l2;
				_scale<1?(_scale=1):null;
				
				html.scaleX=_scale;
				html.scaleY=_scale;
				if(html.getBounds(this).width>7500)
					html.scaleX=7500/html.width;
				if(html.getBounds(this).height>7500)
					html.scaleX=7500/html.height;
				if(html.scaleX<1)
					html.scaleX=1;
				html.scaleY=html.scaleX;
				
				_scaleCenter.x=(points[0].current.x+points[1].current.x)/2;
				_scaleCenter.y=(points[0].current.y+points[1].current.y)/2-y;
				
				html.x=html.x+0.9*((_scaleCenter.x-html.scaleX*_transformPoint.x)-html.x);
				html.y=html.y+0.9*((_scaleCenter.y-html.scaleY*_transformPoint.y)-html.y);
			}
		}
		
		public function onTouchEnd(event:TouchEvent):void{
			_touchManager.updatePoint(event);
			_selectEnabled=true;
		}
		
		private var _transformPoint:Point=new Point();
		private var _scale:Number=1;
		private var _scaleCenter:Point=new Point();
		
		public function onEnterFrame(event:Event):void{
			html.x=html.x+0.2*((_scaleCenter.x-html.scaleX*_transformPoint.x)-html.x);
			html.y=html.y+0.2*((_scaleCenter.y-html.scaleY*_transformPoint.y)-html.y);
			
			
			var bounds:Rectangle=html.getBounds(this);
			if(bounds.left>0)
				html.x=0;
			if(bounds.right<_width)
				html.x=_width-bounds.width;
			if(bounds.top>0)
				html.y=0;
			if(bounds.bottom<_height)
				html.y=_height-bounds.height;
		}
	}
}